package com.haojiangbo.agent;

import com.haojiangbo.hander.NginxChangeHander;
import com.haojiangbo.hander.PostManHander;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.fengfei.lanproxy.common.container.Container;
import org.fengfei.lanproxy.protocol.Constants;
import org.fengfei.lanproxy.server.config.ProxyConfig;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;


/**
 * 不知道起什么名字好,暂且叫nginx吧
 *
 * 他的作用是从 mping 映射中找出 二级域名和端口号的映射关系 再建立1层链接
 *
 *
 */
public class NginxTcpInit implements Container {
    private static Logger logger = LoggerFactory.getLogger(NginxTcpInit.class);
    public  static ConcurrentHashMap <String,Channel> hostMapping = new ConcurrentHashMap<>();
    private NioEventLoopGroup serverWorkerGroup;
    private NioEventLoopGroup serverBossGroup;
    public NginxTcpInit(){
        serverBossGroup = new NioEventLoopGroup();
        serverWorkerGroup = new NioEventLoopGroup();
    }

    @Override
    public void start() {
        ServerBootstrap httpServerBootstrap = new ServerBootstrap();
        httpServerBootstrap .childOption(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(1024, 1024*128, 1024*5000*10)).
        //childOption(ChannelOption.SO_KEEPALIVE, true).
                group(serverBossGroup, serverWorkerGroup).channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {

                    @Override
                    public void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast(new NginxChangeHander());
                    }
                });

        try {
            logger.info("nginx server start on port " + ProxyConfig.getInstance().getNginxPort());
            httpServerBootstrap.bind(ProxyConfig.getInstance().getConfigServerBind(),
                    ProxyConfig.getInstance().getNginxPort()).get();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
      //  startUserLinkded();
    }


    /**
     * 开启和公网端口的链接
     */
    public void startUserLinkded(){
        ConcurrentHashMap<String,Integer> hostName2protMapping  =  ProxyConfig.hostName2protMapping;
        final Bootstrap postMain = new Bootstrap();
        postMain.group(serverBossGroup).
                channel(NioSocketChannel.class);
        postMain.handler(new ChannelInitializer<SocketChannel>(){
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                ch.pipeline().addLast(new PostManHander());
            }
        });
        if(null != hostName2protMapping){
            final Set<Map.Entry<String,Integer>> entrySet = hostName2protMapping.entrySet();
            for(final Map.Entry<String,Integer> item : entrySet){
            postMain.connect("127.0.0.1",item.getValue())
                        .addListener(new ChannelFutureListener() {
                            @Override
                            public void operationComplete(ChannelFuture future) throws Exception {
                                if (future.isSuccess()) {
                                    final Channel postManChange = future.channel();
                                    hostMapping.put(item.getKey(),postManChange);
                                    logger.info("客户端连接成功 == k = {} = {}",item.getKey(), postManChange);
                                   /* ctx.channel().attr(Constants.NEXT_CHANNEL).set(postManChange);
                                    postManChange.attr(Constants.NEXT_CHANNEL).set(ctx.channel());*/
                                }
                            }
                        });
            }
        }

    }


    @Override
    public void stop() {
        serverBossGroup.shutdownGracefully();
        serverWorkerGroup.shutdownGracefully();
    }

}
